#!/usr/bin/env python

from backupManager.backupManager import backupManager
from backupManager.drive import drive
import os
from shutil import copy2 as copy
from shutil import rmtree

testDir = "testFiles\\"
testFile = "icon.png"

driveDict = { 'content' : {'letter':'H', 'path':'H:\\'},
              'backup1' : {'letter':'I', 'path':'I:\\'},
              'backup2' : {'letter':'J', 'path':'J:\\'},
              }

def chooseDrives():
    driveDict = {}
    driveDict['content'] = raw_input("Please provide the content drive letter:")
    driveDict['content'] = { 'letter':driveDict['content'], 'path':driveDict['content'] + ":\\" }
    driveDict['backup1'] = raw_input("Please provide the first backup drive letter:")
    driveDict['backup1'] = { 'letter':driveDict['backup1'], 'path':driveDict['backup1'] + ":\\" }
    driveDict['backup2'] = raw_input("Please provide the second backup drive letter:")
    driveDict['backup2'] = { 'letter':driveDict['backup2'], 'path':driveDict['backup2'] + ":\\" }
    return driveDict

def clearDrives(drives):
    print 'Clearing drives...'
    for dictObj in drives:
        drive = dictObj['path']
        for file in os.listdir(drive):
            path = os.path.join(drive,file)
            try:
                if os.path.isfile(path):
                    os.unlink(path)
                else:
                    rmtree(path)
            except Exception, e:
                print e
                raise
    print 'Drives cleared!'
    
def addDrive(func,letter,path):
    result = func(letter,path)
    if result == backupManager.MISSING:
        print '{0} is not connected! Aborting tests...'.format(path)
        os.sys.exit(1)
    elif result == backupManager.UNNAMED:
        print '{0} is not named! Aborting tests...'.format(path)
        os.sys.exit(1)
    
def setup():
    global driveDict
    buObj = backupManager('test')
    if 'content' not in driveDict or 'backup1' not in driveDict or 'backup2' not in driveDict:
        driveDict = chooseDrives()
    clearDrives(driveDict.values())
    print 'Adding drives to backup manager...'
    addDrive(buObj.addContentDrive,driveDict['content']['letter'],driveDict['content']['path'])
    addDrive(buObj.addBackupDrive,driveDict['backup1']['letter'],driveDict['backup1']['path'])
    addDrive(buObj.addBackupDrive,driveDict['backup2']['letter'],driveDict['backup2']['path'])
    print 'Drives added!'
    print
    print
    return buObj
    
def resetDrives(buObj,mode):
    global driveDict
    clearDrives(driveDict.values())
    os.makedirs(driveDict['backup1']['path']+'test/')
    os.makedirs(driveDict['backup2']['path']+'test/')
    if mode == backupManager.BACKUP or mode == backupManager.ALL:
        copy(os.path.join(testDir,testFile),driveDict['backup1']['path']+'test/'+testFile)
    if mode == backupManager.CONTENT or mode == backupManager.ALL:
        copy(os.path.join(testDir,testFile),driveDict['content']['path']+testFile)
    buObj.refreshDrives(backupManager.ALL)
    
def testBackup(buObj):
    global driveDict
    testStart('Backup')
    #print 'Testing backup...'
    resetDrives(buObj,backupManager.CONTENT)
    errors = buObj.backupNewFiles()
    for error in errors:
        print error
    testPass = False
    if os.path.exists(driveDict['backup1']['path']+'test/'+testFile) or os.path.exists(driveDict['backup2']['path']+'test/'+testFile):
        testPass = True
    testResult('Backup',testPass)
        
def testRestore(buObj):
    testStart('Restore')
    resetDrives(buObj,backupManager.BACKUP)
    errors = buObj.restoreOldFiles()
    for error in errors:
        print error
    testPass = False
    if os.path.exists(driveDict['content']['path']+testFile):
        testPass = True
    testResult('Restore',testPass)  

def testDuplicates(buObj):
    testStart('Duplicate')
    resetDrives(buObj,backupManager.ALL)
    copy(os.path.join(testDir,testFile),driveDict['backup2']['path']+'test/'+testFile)
    buObj.refreshDrives(backupManager.ALL)
    errors = buObj.backupNewFiles()
    for error in errors:
        print error
    testPass = False
    if not os.path.exists(driveDict['backup1']['path']+'test/'+testFile) and os.path.exists(driveDict['backup2']['path']+'test/'+testFile):
        testPass = True
    elif not os.path.exists(driveDict['backup2']['path']+'test/'+testFile) and os.path.exists(driveDict['backup1']['path']+'test/'+testFile):
        testPass = True
    testResult('Duplicate',testPass)

def testRemoveOldFiles(buObj):
    testStart('Old Files')
    resetDrives(buObj,backupManager.BACKUP)
    errors = buObj.backupNewFiles()
    for error in errors:
        print error
    testPass = False
    if not os.path.exists(driveDict['backup1']['path']+'test/'+testFile):
        testPass = True
    testResult('Old Files',testPass)
    
def testSkipList(buObj):
    testStart('Skip List')
    resetDrives(buObj,backupManager.CONTENT)
    os.makedirs(driveDict['content']['path']+'.Trash-500/')
    copy(os.path.join(testDir,testFile),driveDict['content']['path']+'.Trash-500/'+testFile)
    buObj.addSkip('.Trash-500')
    buObj.refreshDrives(backupManager.CONTENT)
    errors = buObj.backupNewFiles()
    buObj.setSkipList([])
    for error in errors:
        print error
    testPass = False
    if not os.path.exists(driveDict['backup1']['path']+'test/.Trash-500/') and not os.path.exists(driveDict['backup2']['path']+'test/.Trash-500/'):
        testPass = True
    testResult('Skip List',testPass)
    
def testStart(name):
    print 'Testing {0}'.format(name)
    print '-----------------------------'
        
def testResult(name,result):
    print '-----------------------------'
    if result:
        print '{0} test: PASS'.format(name)
    else:
        print '{0} test: FAIL'.format(name)
        print '!!!!!!!!!!!! Failed test! Aborting. !!!!!!!!!!!!!!!!!!'
        os.sys.exit(1)
    print
    print
        
def main():
    buObj = setup()
    testBackup(buObj)
    testRestore(buObj)
    testDuplicates(buObj)
    testRemoveOldFiles(buObj)
    testSkipList(buObj)
main()
    